package com.songyang.yougnsql.core.version;

import com.songyang.yougnsql.core.transaction.TransactionManager;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * @ClassName Transaction
 * @Description vm对事物的抽象，该事物是在内存中表现的事务
 * @date 2022/12/16 10:40
 * @Author yanceysong
 * @Version 1.0
 */
public class Transaction {
    /**
     * 事务的隔离级别 读取已提交
     */
    public static final int READ_COMMITTED = 0;
    /**
     * 事务的隔离级别 可重复读
     */
    public static final int REPEATABLE_READ = 1;
    /**
     * 事务的隔离级别 读取未提交
     */
    public static final int READ_UNCOMMITTED = 2;
    /**
     * 事务的隔离级别 可串行化
     */
    public static final int SERIALIZABLE = 3;
    private boolean autoAborted;
    /**
     * 事务的id
     */
    private long xid;
    /**
     * 事务的隔离级别
     */
    private int level;
    /**
     * 当前事务开启的时候所有的事务的xid
     */
    private Set<Long> xidSnapshot;

    /**
     * @param xid    事务的id
     * @param level  隔离级别
     * @param active 当前活跃的所有事务
     * @return Transaction
     */
    public static Transaction newTransaction(long xid, int level, Map<Long, Transaction> active) {
        Transaction transaction = new Transaction();
        transaction.setXid(xid);
        transaction.level = level;
        if (level != Transaction.READ_COMMITTED) {
            transaction.xidSnapshot = new HashSet<>();
            transaction.xidSnapshot.addAll(active.keySet());
        }
        return transaction;
    }

    /**
     * 当前事务的xid是否在这个事务开启之前就活跃状态
     *
     * @param xid 事务的id
     * @return 返回结果
     */
    public boolean isInSnapshot(long xid) {
        if (xid == TransactionManager.SUPER_XID) {
            return false;
        }
        return xidSnapshot.contains(xid);
    }

    public long getXid() {
        return xid;
    }

    public void setXid(long xid) {
        this.xid = xid;
    }

    public int getLevel() {
        return level;
    }

    public boolean isAutoAborted() {
        return autoAborted;
    }

    public void setAutoAborted(boolean autoAborted) {
        this.autoAborted = autoAborted;
    }
}
